package com.wn.order.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.utils.ZxingUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wn.common.entity.Const;
import com.wn.common.entity.MyParam;
import com.wn.common.entity.MyRsp;
import com.wn.common.pojo.Orders;
import com.wn.common.pojo.Percentage;
import com.wn.order.common.DataGridResponse;
import com.wn.order.feign.UserFeign;
import com.wn.order.mapper.OrderMapper;
import com.wn.order.service.OrderService;
import com.wn.order.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @BelongsProject: shared_parking
 * @BelongsPackage: com.wn.order.service.impl
 * @Author: 段彪
 * @CreateTime: 2020-06-11 12:15
 * @Description: 订单
 */
@Service
public class OrderImpl implements OrderService {

    private final static Logger logger = LoggerFactory.getLogger(OrderImpl.class);
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    UserFeign userFeign;

    // 支付宝当面付2.0服务
    private static AlipayTradeService tradeService;

    //查询所有
    @Override
    public List<Orders> getAll() {
        List<Orders> all = orderMapper.getAll();
        return all;
    }

    //生成订单
    @Override
    public MyRsp addOrders(GenerateOrdersVo OrdersVo) {
        Orders orderGetInfo = new Orders();
        String oId = "tradeprecreate" + System.currentTimeMillis()
                + (long) (Math.random() * 10000000L);
        //1.订单id
        orderGetInfo.setOId(oId);
        //向车位信息表添加oid
        orderMapper.updateByOrderId(oId, OrdersVo.getParkingId());
        //startTime.1开始时间
        long startTime = System.currentTimeMillis();
        SimpleDateFormat time1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String etime1 = time1.format(new Date(startTime));
        //endTime.2延时函数
        long eTime1 = System.currentTimeMillis() + 5 * 60 * 1000;//延时函数，单位毫秒，这里是延时了5分钟
        SimpleDateFormat time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String etime2 = time2.format(new Date(eTime1));//
        //2.开始时间
        orderGetInfo.setOStartTime(etime1);
        //3.结束时间
        orderGetInfo.setOEndTime(etime2);
        //4.车位id
        orderGetInfo.setParkingId(OrdersVo.getParkingId());
        Orders allId = orderMapper.getAllId(OrdersVo.getParkingId());
        //5.出租方id
        orderGetInfo.setRenterId(allId.getRenterId());
        //6.物业id
        orderGetInfo.setPropertyId(allId.getPropertyId());
        //7.抢租客id
        orderGetInfo.setTenantId(allId.getTenantId());
        //8.平台id
        orderGetInfo.setPlatformId("234aa721-ae09-11ea-ac4b-0242ac110006");
        //9.金额
        BigDecimal money = new BigDecimal(OrdersVo.getMoney());
        String coId = UUID.randomUUID().toString();
        //9.1生成评论
        orderMapper.addComment(coId,oId,OrdersVo.getUsername());

        orderGetInfo.setMoney(money);
        //10.用户名
        orderGetInfo.setRealName(OrdersVo.getUsername());

        Integer integer = orderMapper.addOrders(orderGetInfo);

        if (integer > 0) {
            return MyRsp.success2(Const.Status.STATUS_SUCCESS,OrdersVo.getUsername(),oId);
        } else {
            return MyRsp.success1(Const.Status.STATUS_ERROR, "添加失败");
        }
    }

    //批量逻辑删除
    @Override
    public MyRsp deleteOrdersById(String oId) {
        Integer integer = orderMapper.deleteOrdersById(oId);
        if (integer > 0) {
            return MyRsp.success1(Const.Status.STATUS_SUCCESS, "删除成功");
        } else {
            return MyRsp.success1(Const.Status.STATUS_ERROR, "删除失败");
        }
    }

    @Override
    public List<PropertyLessorVo> getTPLAll() {

        return null;
    }


    //根据用user模糊查询
    @Override
    public List<ViewEarnings> fuzzQueryById(String username) {
        return null;
    }

    //分页查询
    @Override
    public PageInfo<Orders> pagingQuery(MyParam<Orders> myParam) {
        PageHelper.startPage(myParam.getMyPage().getPageNum(), myParam.getMyPage().getPageSize());
        String[] pageParam = myParam.getPageParam();
        //遍历数组
        for (int i = 0; i < pageParam.length; i++) {
            PageHelper.orderBy(pageParam[i]);  //  "ID  DESC" ,"AGE  ASC"
        }
        List<Orders> orders = orderMapper.pagingQuery();
        return new PageInfo<Orders>(orders);
    }

    //订单查询
    @Override
    public List<PropertyLessorVo> queryOrder() {
        List<PropertyLessorVo> propertyLessorVos = orderMapper.queryName();
//        PropertyLessorVo propertyVo1 = orderMapper.queryProperty();
//        PropertyLessorVo propertyVo2 = orderMapper.queryRenter();
//        System.out.println(propertyVo+" "+propertyVo1+" "+propertyVo2);
//        PropertyLessorVo propertyLessorVo = orderMapper.queryPropertyLessorVo();
        System.out.println(propertyLessorVos);
        return propertyLessorVos;
    }

    //平台方分页查询
    @Override
    public DataGridResponse getAllOrder(Integer page, Integer rows, String name) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        //开启分页框架插件
        Page<Object> PageInfo = PageHelper.startPage(page, rows);

        List<PropertyLessorVo> categories = orderMapper.getProperty(name);

        List<PropertyLessorVo> propertyLessorVos1 = orderMapper.queryRenterProperty();//物业名

        for (int i = 0; i < categories.size(); i++) {
                categories.get(i).setRenterName(propertyLessorVos1.get(i).getRenterName());
                categories.get(i).setPropertyName(propertyLessorVos1.get(i).getPropertyName());
        }
        //查询数据r
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, categories);
    }
    //出租方
    @Override
    public DataGridResponse getLessonOrder(Integer page, Integer rows, String name,String token) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        //开启分页框架插件
        Page<Object> PageInfo = PageHelper.startPage(page, rows);

        MyRsp userInfo = userFeign.getUserInfo(token);

        LinkedHashMap<String,Object> current = (LinkedHashMap<String, Object>) userInfo.getContent();
        logger.info("/////,{}",userInfo);
        List<PropertyLessorVo> categories = orderMapper.getLessonOrder((String) current.get("uid"),name);
        //查询数据r
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, categories);
    }



    //物业方收益
    @Override
    public DataGridResponse getPropertyOrder(Integer page, Integer rows, String name,String token) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        //开启分页框架插件
        Page<Object> PageInfo = PageHelper.startPage(page, rows);
        MyRsp user = userFeign.getUserInfo(token);

        LinkedHashMap<String,Object> currentUser = (LinkedHashMap<String, Object>) user.getContent();
        logger.info("////,{}",user);
        List<PropertyLessorVo> categories = orderMapper.getPropertyOrder((String) currentUser.get("uid"),name);

        //查询数据r
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, categories);
    }

    //普通结算
    @Override
    public BigDecimal SettlementMoney(Integer hour) {
        BigDecimal bigDecimal = orderMapper.SettlementMoney(hour);
        return bigDecimal;
    }
    //查看收益
    @Override
    public DataGridResponse ViewEarnings(Integer page, Integer rows, String name) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        //开启分页
        Page<Object> PageInfo = PageHelper.startPage(page, rows);
        //查询平台收益
        List<ViewEarnings> platformCommission = orderMapper.getPlatformCommission(name);
        //物业方收益
        List<ViewEarnings> propertyCommission = orderMapper.getPropertyCommission();

        for (int i = 0; i < platformCommission.size(); i++) {
            if (platformCommission.get(i).getLessorIncome()==null){
                platformCommission.get(i).setLessorIncome(new BigDecimal("0"));
            }
            platformCommission.get(i).setPropertyIncome(propertyCommission.get(i).getPropertyIncome());
        }
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, platformCommission);
    }

    //查询提成
    @Override
    public DataGridResponse getAllPercentage(Integer page, Integer rows, String name) {
        Page<Object> PageInfo = PageHelper.startPage(page, rows);
        List<Percentage> allPercentage = orderMapper.getAllPercentage();
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, allPercentage);
    }

    //修改提成点
    @Override
    public MyRsp updatePercentage(String tcId, String commission) {
        BigDecimal commissions = new BigDecimal(commission);
        Integer integer = orderMapper.updatePercentage(tcId, commissions);
        if (integer > 0) {
            return MyRsp.success1(Const.Status.STATUS_SUCCESS, "修改成功");
        } else {
            return MyRsp.success1(Const.Status.STATUS_ERROR, "修改失败");
        }
    }

    //车位信息
    @Override
    public MyRsp getCarportVo(String cpId) {
        CarPortAreaVillageVo carportVo = orderMapper.getCarportVo(cpId);
        if (carportVo != null) {
            return MyRsp.success(carportVo);
        } else {
            return MyRsp.success1(Const.Status.STATUS_ERROR, "查询失败");
        }
    }

    //支付宝支付
    @Override
    public MyRsp Pay(String oid) {
        System.out.println(oid);
        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
        // 需保证商户系统端不能重复，建议通过数据库sequence生成，
//        String outTradeNo = "tradeprecreate" + System.currentTimeMillis()
//                + (long) (Math.random() * 10000000L);
        String outTradeNo = oid;
        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = "蜗牛共享车位";

        // (必填) 订单总金额，单位为元，不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = "0.01";

        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";

        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";

        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = "购买商品3件共20.00元";

        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");

        // 支付超时，定义为120分钟
        String timeoutExpress = "90m";

        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 创建一个商品信息，参数含义分别为商品id（使用国标）、名称、单价（单位为分）、数量，如果需要添加商品类别，详见GoodsDetail
        GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "xxx面包", 1000, 1);
        // 创建好一个商品后添加至商品明细列表
        goodsDetailList.add(goods1);

        // 继续创建并添加第一条商品信息，用户购买的产品为“黑人牙刷”，单价为5.00元，购买了两件
        GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
        goodsDetailList.add(goods2);

        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl("http://y46d2q.natappfree.cc/order/aliPayCallback")//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setGoodsDetailList(goodsDetailList);

        Configs.init("zfbinfo.properties");
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("支付宝预下单成功: )");
                AlipayTradePrecreateResponse response = result.getResponse();
                String qrCode = response.getQrCode();
                System.out.println(qrCode);

                String filePath = String.format("D:/a/qr-%s.png",
                        response.getOutTradeNo());
                System.out.println("filePath:" + filePath);
                ZxingUtils.getQRCodeImge(response.getQrCode(), 256, filePath);
                return MyRsp.success(response.getQrCode());

            case FAILED:
                System.out.println("支付宝预下单失败!!!");
                return MyRsp.fail().msg("支付宝预下单失败");

            case UNKNOWN:
                System.out.println("系统异常，预下单状态未知!!!");
                return MyRsp.fail().msg("系统异常");

            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                return MyRsp.fail().msg("交易返回异常");
        }
    }

    /**
     * 支付宝回调
     *
     * @param request
     * @return
     */
    @Override
    public String aliPayCallback(HttpServletRequest request) {
        Map<String,String> params = new HashMap<>();

        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for(int i = 0 ; i <values.length;i++){

                valueStr = (i == values.length -1)?valueStr + values[i]:valueStr + values[i]+",";
            }
            //把request对象中的数据存放到map集合找那个
            params.put(name,valueStr);
        }
        //非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.
        params.remove("sign_type");

        try {
            //延签
            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());

            if(!alipayRSACheckedV2){
                System.out.println("非法请求,验证不通过,再恶意请求我就报警找网警了");
                return "failed";
            }
        } catch (AlipayApiException e) {
            System.out.println("支付宝验证回调异常"+e);
            return "failed";
        }

        Set<String> keySet = params.keySet();
        keySet.forEach(s ->{
            String val = params.get(s);
            System.out.println(s+":"+val);
        });

        //获取到交易状态
        String trade_status = params.get("trade_status");
        //判断交易是成功还是失败
        if(trade_status.equals("TRADE_SUCCESS")){//支付成功
            //把订单的支付状态修改成已支付
            //1.获取到交易的订单编号
            String orderId = params.get("out_trade_no");
            //2.根据订单编号修改订单
            orderMapper.updateOrderStatus(orderId);
            return "success";
        }else{//支付失败
            return "failed";
        }


    }

    /**
     * 支付宝查询订单，防止支付宝回调失败,造成单边账
     *
     * @param myParam
     * @return
     */
    @Override
    public MyRsp queryAliPayOrderStatus(MyParam<Orders> myParam) {
        String outTradeNo = myParam.getT().getOId();
        Orders payCode = orderMapper.getPayCode(outTradeNo);
        if (payCode.getOCode()==1){
            return MyRsp.success1(Const.Status.STATUS_SUCCESS,"支付成功");
        }else {
            return MyRsp.success1(Const.Status.STATUS_ERROR,"支付失败");
        }

    }
    //我的订单信息
    @Override
    public MyRsp myOrders(MyParam<MyOrderVo> myParam) {
       if (myParam.getPageParam() != null){
            //pageHelper排序
            PageHelper.orderBy(myParam.getPageParam()[0]);
            System.out.println(myParam.getPageParam()[0]);
       }

        List<MyOrderVo> myOrder = orderMapper.getMyOrder(myParam.getT());
        for (int i = 0; i < myOrder.size(); i++){
            if(myOrder.get(i).getOcode()==0){
                myOrder.get(i).setPayCodeName("未支付");
            }else if(myOrder.get(i).getOcode()==1){
                myOrder.get(i).setPayCodeName("已支付");
            }else{
                myOrder.get(i).setPayCodeName("超时支付");
            }
            if(myOrder.get(i).getCommentcode()==0){
                myOrder.get(i).setCommentName("未评论");
            }else if(myOrder.get(i).getCommentcode()==1){
                myOrder.get(i).setCommentName("已评论");
            }
        }
        PageInfo<MyOrderVo> myOrderVoPageInfo = new PageInfo<>(myOrder);
        return MyRsp.success(myOrderVoPageInfo);
    }
    //物业方收益
    @Override
    public DataGridResponse PropertyCommission(Integer page, Integer rows,String name,String token) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        Page<Object> PageInfo = PageHelper.startPage(page, rows);
        MyRsp feign = userFeign.getUserInfo(token);
        LinkedHashMap<String,Object> content = (LinkedHashMap<String,Object>)feign.getContent();
        List<ViewEarnings> viewEarnings = orderMapper.PropertyCommission((String) content.get("uid"),name);
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, viewEarnings);
    }

    //出租方收益
    @Override
    public DataGridResponse LessorCommission(Integer page, Integer rows,String name,String token) {
        if (name != null && !name.equals("")) {
            name = "%" + name + "%";
        }
        Page<Object> PageInfo = PageHelper.startPage(page, rows);
        MyRsp feign = userFeign.getUserInfo(token);
        LinkedHashMap<String,Object> content = (LinkedHashMap<String,Object>)feign.getContent();
        List<ViewEarnings> viewEarningsList = orderMapper.LessorCommission((String) content.get("uid"),name);
        long total = PageInfo.getTotal();
        return new DataGridResponse((int) total, viewEarningsList);
    }

//    @Override
//    public MyParam<MyOrderVo> myOrderName(MyParam<MyOrderVo> myParam) {
//        String username= myParam.getT().getUsername();
//        Orders ordersByName = orderMapper.getOrdersByName(username);
//        myParam.getT().setRealName(ordersByName.getRealName());
//        return myParam;
//    }
}
